const os = require('os')

// CPU监控相关
class CpuUsage{
    constructor(){
        this.cpuUsageMSDefault = 1000; // CPU 利用率默认时间段
        this.sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
    }
    _getCPUInfo() {
        const cpus = os.cpus();
        let user = 0, nice = 0, sys = 0, idle = 0, irq = 0, total = 0;

        for (let cpu in cpus) {
            const times = cpus[cpu].times;
            user += times.user;
            nice += times.nice;
            sys += times.sys;
            idle += times.idle;
            irq += times.irq;
        }

        total += user + nice + sys + idle + irq;

        return {
            user,
            sys,
            idle,
            total,
        }
    }
    async getCPUUsage(options={}) {
        let { cpuUsageMS, percentage } = options;
        cpuUsageMS = cpuUsageMS || this.cpuUsageMSDefault;
        const t1 = this._getCPUInfo(); // t1 时间点 CPU 信息
    
        await this.sleep(cpuUsageMS);
    
        const t2 = this._getCPUInfo(); // t2 时间点 CPU 信息
        const idle = t2.idle - t1.idle;
        const total = t2.total - t1.total;
        let usage = 1 - idle / total;
    
        if (percentage) usage = (usage * 100.0).toFixed(2) + "%";
    
        return usage;
    }
}

// 内存监控相关
class MemoryUsage{
    constructor(){
        // 获取系统空闲内存
        this.systemFree = os.freemem();
        // 获取系统总内存
        this.systemTotal = os.totalmem();
    }
    getMemoryUsage(options={}){
        let { percentage } = options;
        let usage = 1 - this.systemFree / this.systemTotal
        if (percentage) usage = (usage * 100.0).toFixed(2) + "%";
        return usage;
    }
}

class osUtils {
    constructor(){
        this.ms = 1000
    }
    async _getOS(callback){
        let cpu = await new CpuUsage().getCPUUsage({percentage: true})
        callback({
            cpu,
            memory: new MemoryUsage().getMemoryUsage({percentage: true})
        })
    }
    getOsInfoOfMS(callback, ms){
        let MS = ms || this.ms
        setInterval(async ()=>{
            this._getOS(callback)
        }, MS)
    }
    getOsInfo(callback){
        this._getOS(callback)
    }
}

module.exports = osUtils